package com.txsj.scan.presenter;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;

import com.greendao.EpcInfoDao;
import com.greendao.RecordInfoDao;
import com.txsj.scan.Constants;
import com.txsj.scan.base.BasePresenter;
import com.txsj.scan.bean.BaseListResult;
import com.txsj.scan.bean.BaseResult;
import com.txsj.scan.bean.EpcInfo;
import com.txsj.scan.bean.GlobalGoodsInfo;
import com.txsj.scan.bean.GoodsClassify;
import com.txsj.scan.bean.GoodsInfo;
import com.txsj.scan.bean.RecordInfo;
import com.txsj.scan.bean.UpdateBean;
import com.txsj.scan.db.GreenDaoUtils;
import com.txsj.scan.http.ApiServer;
import com.txsj.scan.http.requestframework.RetrofitManager;
import com.txsj.scan.utils.DeviceUtils;
import com.txsj.scan.utils.GZIPUtils;
import com.txsj.scan.utils.GsonFactory;
import com.txsj.scan.utils.MD5Util;
import com.txsj.scan.utils.PreferenceUtil;
import com.txsj.scan.utils.Trace;
import com.txsj.scan.view.IGoodsListView;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

/**
 * @Created by WangChuangJun on 2018/11/22
 * @Describe
 */
public class GoodsListPresenter extends BasePresenter<IGoodsListView> {
    private static final int RETRY_LABEL = 0x141;
    private static final int RETRY_CACHE_GLOBAL = 0x142;
    private static final int ON_LOADING = 0x147;
    private static final int ON_SUCCESS = 0x148;
    private static final int ON_ERROR = 0x149;

    // 设置变量
    // 可重试次数
    private int maxConnectCount = 20;
    // 当前已重试次数
    private int currentRetryGoodsCount = 0;//商品的
    private int currentRetryLabelCount = 0;//标签的
    private int currentRetryGlobalCount = 0;//全局商品的
    // 重试等待时间
    private int waitRetryGoodsTime = 0;
    private int waitRetryLabelTime = 0;
    private int waitRetryGlobalTime = 0;//全局商品的
    // 当前分页数量
    private int goodsPageIndex = 1;
    private int tagPageIndex = 1;

    List<RecordInfo> recordInfoList;
    private long times_long = 1000*60*30;//时间差
//    private long times_long = 1000*30;//时间差

    private long time_difference = 0;
    private int epcLimit = 10000;//标签缓存每页加载的条数

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case ON_LOADING:
                    if (null!=view)
                        view.onLoading();
                    break;
                case ON_ERROR:
                    if (null!=view)
                        if (null != msg.obj) {
                            String error = (String) msg.obj;
                            view.onLoadCacheError(error);
                        }
                    break;
                case ON_SUCCESS:
                    if (null!=view)
                        view.onLoadCacheSuccess();
                    break;
                case RETRY_CACHE_GLOBAL:
                    gotoHttpData();
                    break;
                case RETRY_LABEL:
                    getGoodsAndTagHttp();
                    break;

            }
        }
    };


    public GoodsListPresenter(IGoodsListView view) {
        super(view);
    }

    @Override
    protected void initModel() {

    }

    /**
     * 获取商品分类列表
     */
    public void getGoodsTypeHttp() {
        Map<String, String> params = new HashMap<>();
        StringBuilder builder = new StringBuilder();
        builder.append(PreferenceUtil.getInstance().getString(PreferenceUtil.BRAND_ID, ""));
        builder.append("|");
        builder.append(PreferenceUtil.getInstance().getInt(PreferenceUtil.USER_ID, 0));
        builder.append("|");
        builder.append(PreferenceUtil.getInstance().getString(PreferenceUtil.TOKEN, ""));
        builder.append("|");
        builder.append(0);
        builder.append("|");
        params.put("brandtoken", builder.toString());
        params.put("timeStamp", System.currentTimeMillis() / 1000 + "");//加时间戳参数
        params.put("sign", MD5Util.md5(params));//md5加密并加参数
        view.onLoading();
        RetrofitManager.getDefault().create(ApiServer.class).getGoodsType(RetrofitManager.getHeader(), params)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<BaseListResult<GoodsClassify>>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        compositeDisposable.add(d);
                    }

                    @Override
                    public void onNext(BaseListResult<GoodsClassify> result) {
                        if (result.isSuccess()) {
                            if (null != result.getData() && result.getData().size() > 0) {
                                view.onClassifySuccess(result.getData());
                            } else {
                                view.onError("暂无商品分类");
                            }
                        } else {
                            view.onError(result.getMsg());
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        view.onError("网络异常");
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    /**
     * 请求商品列表
     * @param goods_class_id
     */
    public void getGoodsList(int goods_class_id, final int page, String state, String inventory) {
        Map<String, String> params = new HashMap<>();
        StringBuilder builder = new StringBuilder();
        builder.append(PreferenceUtil.getInstance().getString(PreferenceUtil.BRAND_ID, ""));
        builder.append("|");
        builder.append(PreferenceUtil.getInstance().getInt(PreferenceUtil.USER_ID, 0));
        builder.append("|");
        builder.append(PreferenceUtil.getInstance().getString(PreferenceUtil.TOKEN, ""));
        builder.append("|");
        builder.append(0);
        builder.append("|");
        params.put("brandtoken", builder.toString());
        params.put("limit","20");
        params.put("page",page+"");
        params.put("goods_class_id",goods_class_id+"");
        params.put("goods_state",state);
        params.put("has_inventory",inventory);
        params.put("timeStamp", System.currentTimeMillis() / 1000 + "");//加时间戳参数
        params.put("sign", MD5Util.md5(params));//md5加密并加参数
        RetrofitManager.getDefault().create(ApiServer.class).getGoodsList(RetrofitManager.getHeader(),params)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<BaseListResult<GoodsInfo>>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        compositeDisposable.add(d);
                    }

                    @Override
                    public void onNext(BaseListResult<GoodsInfo> result) {
                        if (result.isSuccess()){
                            if (null != result.getData() && result.getData().size() > 0){
                                view.onGoodsInfoListSuccess(result.getData());
                            }else {
                                if (page == 1) {
                                    view.onEmpty("暂无数据");
                                }else {
                                    view.onLoadMoreEnd("加载完毕");
                                }
                            }
                        }else {
                            if (page == 1) {
                                view.onLoadError("网络异常");
                            }else {
                                view.onLoadMoreError("加载失败");
                            }
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        Trace.e("wcj===="+e.getMessage());
                        if (page == 1) {
                            view.onLoadError("网络异常");
                        }else {
                            view.onLoadMoreError("加载失败");
                        }
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    /**
     * 获得商品及标签数据
     */
    public void getGoodsAndTagHttp() {
        refresh();
         new Thread(new Runnable() {
            @Override
            public void run() {
                //子线程初始化一个looper对象
                Looper.prepare();
//                getGoodsLabel();
                getEpcRetrofitHttp();
                Looper.loop();
            }
        }).start();
    }

    /**
     * 在调拨完成后更新
     * 商品库和标签库
     */
    private void refresh(){
        currentRetryGoodsCount = 0;
        currentRetryLabelCount = 0;
        waitRetryGoodsTime = 0;
        waitRetryLabelTime = 0;
        goodsPageIndex = 1;
        tagPageIndex = 1;
        PreferenceUtil.getInstance().commitBoolean(PreferenceUtil.FIRST_LOAD_LABEL_AND_GOODS, true);
        GreenDaoUtils.getSingleTon().getmDaoSession().getEpcGoodsInfoDao().deleteAll();
        GreenDaoUtils.getSingleTon().getmDaoSession().getEpcInfoDao().deleteAll();
        GreenDaoUtils.getSingleTon().getmDaoSession().getUnusefulEpcDao().deleteAll();
        GreenDaoUtils.getSingleTon().getmDaoSession().getTagInfoDao().deleteAll();
    }

    /**
     * 获取品牌下所有的商品数据
     * 含有断线重连机制，一直重连
     */
//    private void getGoodsLabel() {
//        Map<String, String> params = new HashMap<>();
//        StringBuilder builder = new StringBuilder();
//        builder.append(PreferenceUtil.getInstance().getString(PreferenceUtil.BRAND_ID,""));
//        builder.append("|");
//        builder.append(PreferenceUtil.getInstance().getInt(PreferenceUtil.USER_ID,0));
//        builder.append("|");
//        builder.append(PreferenceUtil.getInstance().getString(PreferenceUtil.TOKEN,""));
//        builder.append("|");
//        builder.append(0);
//        builder.append("|");
//        params.put("brandtoken", builder.toString());
//        params.put("select_brand", PreferenceUtil.getInstance().getString(PreferenceUtil.BRAND_ID,""));
//        params.put("brandid", PreferenceUtil.getInstance().getString(PreferenceUtil.BRAND_ID,""));
//        params.put("page_index", goodsPageIndex + "");
//        params.put("page_size", "10000");
//        params.put("timeStamp", System.currentTimeMillis() / 1000 + "");//加时间戳参数
//        params.put("sign", MD5Util.md5(params));//md5加密并加参数
//
//        Map<String,String> header = RetrofitManager.getHeader();
//        header.put("gzip_type","1");
//
//        handler.sendEmptyMessage(ON_LOADING);
//        RetrofitManager.getDefault().create(ApiServer.class).getEpcGoodsByteListUrl(header, params)
//                .enqueue(new Callback<ResponseBody>() {
//                    @Override
//                    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
//                        try {
//                            if (null != response && null != response.body()) {
//                                if (null != response.body().source()) {
//                                    //获得response中的body的字节数组
////                                    byte[] data = response.body().bytes();
//                                    //通过UTF-8解压缩成json字符串
//                                    String json = GZIPUtils.uncompressToString(response.body().source().readByteArray(), GZIPUtils.GZIP_ENCODE_UTF_8);
//                                    //将字符串转换成定义好的数据类型
//                                    JSONObject jsonObject = new JSONObject(json);
//
//                                    // 对数据进行操作
//                                    epcGoodsNext(jsonObject);
//                                }else {
//                                    // todo 返回的字节数组无数据
//                                    Message msg = new Message();
//                                    msg.obj = response.message();
//                                    msg.what = ON_ERROR;
//                                    handler.sendMessage(msg);
//                                    Trace.e("wcj:Goods+++++：" + response.message());
//                                }
//                            }else {
//                                // TODO 网络异常
//                                Message msg = new Message();
//                                msg.obj = response.message();
//                                msg.what = ON_ERROR;
//                                handler.sendMessage(msg);
//                                Trace.e("wcj:Goods+++++：" + response.message());
//                            }
//                        } catch (IOException e) {
//                            e.printStackTrace();
//                        } catch (JSONException e) {
//                            e.printStackTrace();
//                        }
//                    }
//
//                    @Override
//                    public void onFailure(Call<ResponseBody> call, Throwable t) {
//                        Message msg = new Message();
//                        msg.obj = t.getMessage();
//                        msg.what = ON_ERROR;
//                        handler.sendMessage(msg);
//                        Trace.e("wcj:Goods+++++：" + t.getMessage());
//                    }
//                });
//    }

    /**
     * 对商品库请求流进行解析
     * @param jsonObject
     */
//    private void epcGoodsNext(JSONObject jsonObject) {
//        boolean isSuccess = jsonObject.optBoolean("success");
//        if (isSuccess) {
//            JSONArray jsonArray = jsonObject.optJSONArray("data");
//            if (jsonArray.length() == 0) return;
//            List<EpcGoodsInfo> list = GsonFactory.getObjectList(jsonArray.toString(),EpcGoodsInfo.class);
//            if (null != list && list.size() > 0) {
//                EpcGoodsInfoDao epcGoodsInfoDao = GreenDaoUtils.getSingleTon().getmDaoSession().getEpcGoodsInfoDao();
//                for (EpcGoodsInfo info : list) {
//                    epcGoodsInfoDao.insertOrReplace(info);
//                }
//                if (list.size() == 10000) {
//                    tagPageIndex++;
//                    getGoodsLabel();
//                    Trace.e("wcj,Tag+++++++++++++++" + goodsPageIndex);
//                } else {
//                    //本地记录一个参数，list.size() < 100：加载完毕
//                    PreferenceUtil.getInstance().commitBoolean(PreferenceUtil.GOODS_IS_LOADED, true);;//本地记录加载成功
//                    handler.sendEmptyMessage(ON_SUCCESS);
//                }
//            } else {
//                //本地记录一个参数，list.size() < 100：加载完毕
//                PreferenceUtil.getInstance().commitBoolean(PreferenceUtil.GOODS_IS_LOADED, true);;//本地记录加载成功
//                handler.sendEmptyMessage(ON_SUCCESS);
//            }
//        }
//    }


    private int retryLabelCount = 0;//重试次数
    private int reTryLabelMax = 20;//重试最大次数，超过就关闭
    private long reTryLabelDelay = 1500;//重试间隔，1.5s
    /**
     * 获取标签数据
     * 韩断线重连机制
     */
    private void getEpcRetrofitHttp() {
        Map<String, String> params = RetrofitManager.getParams();
        params.put("brandid", PreferenceUtil.getInstance().getString(PreferenceUtil.BRAND_ID,""));
        params.put("select_brand", PreferenceUtil.getInstance().getString(PreferenceUtil.BRAND_ID,""));
        params.put("page_index", tagPageIndex + "");
        params.put("page_size", epcLimit +"");

        Map<String,String> header = RetrofitManager.getHeader();
        header.put("gzip_type","1");
        Trace.e("wcj：当前线程"+Looper.myLooper());
        handler.sendEmptyMessage(ON_LOADING);

        time_difference = System.currentTimeMillis();
        if (retryLabelCount != 0){
            Trace.e("重连次数："+ retryLabelCount);
        }
        RetrofitManager.getDefault().create(ApiServer.class).getEpcByteListUrl(header, params)
                .enqueue(new Callback<ResponseBody>() {
                    @Override
                    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                        Trace.e("wcj时间差,压缩后的======="+(System.currentTimeMillis()-time_difference));
                        try {
                            if (null != response && null != response.body()) {
                                if (null != response.body().source() && response.isSuccessful()) {
                                    //获得response中的body的字节数组
//                                    byte[] data = response.body().bytes();
                                    //通过UTF-8解压缩成json字符串
                                    String json = GZIPUtils.uncompressToString(response.body().source().readByteArray(), GZIPUtils.GZIP_ENCODE_UTF_8);
                                    //将字符串转换成定义好的数据类型
                                    final JSONObject jsonObject = new JSONObject(json);
                                    time_difference = System.currentTimeMillis();
                                    // 对数据进行操作
                                    new Thread(new Runnable() {
                                        @Override
                                        public void run() {
                                            epcNext(jsonObject);
                                        }
                                    }).start();

                                }else {
                                    // todo 返回的字节数组无数据
                                    if (retryLabelCount < reTryLabelMax) {
                                        retryLabelCount++;
                                        Message msg = new Message();
                                        msg.what = RETRY_LABEL;
                                        handler.sendMessageDelayed(msg, reTryLabelDelay);
                                    }else {
                                        retryLabelCount = 0;//重置
                                        Message msg = new Message();
                                        msg.obj = "网络异常";
                                        msg.what = ON_ERROR;
                                        handler.sendMessage(msg);
                                    }
                                }
                            }else {
                                // TODO 网络异常
                                if (retryLabelCount < reTryLabelMax) {
                                    retryLabelCount++;
                                    Message msg = new Message();
                                    msg.what = RETRY_LABEL;
                                    handler.sendMessageDelayed(msg, reTryLabelDelay);
                                }else {
                                    retryLabelCount = 0;//重置
                                    Message msg = new Message();
                                    msg.obj = "网络异常";
                                    msg.what = ON_ERROR;
                                    handler.sendMessage(msg);
                                }
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }

                    @Override
                    public void onFailure(Call<ResponseBody> call, Throwable t) {
                        Trace.e("wcj,Tag+++++：" + t.getMessage());
                        if (retryLabelCount < reTryLabelMax) {
                            retryLabelCount++;
                            Message msg = new Message();
                            msg.what = RETRY_LABEL;
                            handler.sendMessageDelayed(msg, reTryLabelDelay);
                        }else {
                            retryLabelCount = 0;//重置
                            Message msg = new Message();
                            msg.obj = "网络异常";
                            msg.what = ON_ERROR;
                            handler.sendMessage(msg);
                        }
                    }
                });
    }

    /**
     * 对标签请求流进行解析
     * @param jsonObject
     */
    private void epcNext(JSONObject jsonObject) {
        Trace.i("wcj："+jsonObject.toString());
        Trace.e("wcj：当前线程"+Looper.myLooper());
        boolean isSuccess = jsonObject.optBoolean("success");
        if (isSuccess) {
            JSONArray jsonArray = jsonObject.optJSONArray("data");
            if (jsonArray.length() == 0)return;
            final List<EpcInfo> list = GsonFactory.getObjectList(jsonArray.toString(),EpcInfo.class);
            if (null != list && list.size() > 0) {
                final EpcInfoDao epcInfoDao = GreenDaoUtils.getSingleTon().getmDaoSession().getEpcInfoDao();
//                for (EpcInfo info : list) {
//                    epcInfoDao.insertOrReplace(info);
//                }
//                epcInfoDao.insertInTx(list);

                epcInfoDao.getSession().runInTx(new Runnable() {
                    @Override
                    public void run() {
                        epcInfoDao.insertOrReplaceInTx(list);
                    }
                });
                if (list.size() == epcLimit) {
                    tagPageIndex++;
                    getEpcRetrofitHttp();
                    Trace.e("wcj,Tag+++++++++++++++" + tagPageIndex);
                } else {
                    //本地记录一个参数，list.size() < 100：加载完毕
                    PreferenceUtil.getInstance().commitBoolean(PreferenceUtil.LABEL_IS_LOADED, true);//本地记录加载成功
                    handler.sendEmptyMessage(ON_SUCCESS);
                    Trace.e("wcj,Tag++++++++++epc.size:"+GreenDaoUtils.getSingleTon().getmDaoSession().getEpcInfoDao().loadAll().size());
                    Trace.e("wcj,Tag++++++++++存库时间差:" + (System.currentTimeMillis() - time_difference));
                }
            } else {
                //本地记录一个参数，list.size() < 100：加载完毕
                PreferenceUtil.getInstance().commitBoolean(PreferenceUtil.LABEL_IS_LOADED, true);//本地记录加载成功
                handler.sendEmptyMessage(ON_SUCCESS);
            }
        } else {
            Message msg = new Message();
            msg.obj = "暂无标签数据数据";
            msg.what = ON_ERROR;
            handler.sendMessage(msg);
            Trace.e("wcj,Tag+++++：" + "数据为空");
        }
    }

    /**
     * 扫描返回的条形码进行商品识别
     * @param data
     */
    public void getBarCodeHttp(String data) {
        Map<String, String> params = new HashMap<>();
        params.put("userid", PreferenceUtil.getInstance().getInt(PreferenceUtil.USER_ID,0)+"");
        params.put("token", PreferenceUtil.getInstance().getString(PreferenceUtil.TOKEN,""));
        params.put("brandid", PreferenceUtil.getInstance().getString(PreferenceUtil.BRAND_ID,""));
        params.put("goodsnum", data);
        params.put("timeStamp", System.currentTimeMillis() / 1000 + "");//加时间戳参数
        params.put("sign", MD5Util.md5(params));//md5加密并加参数
        view.onLoading();
        RetrofitManager.getDefault().create(ApiServer.class).getBarCodeGoods(RetrofitManager.getHeader(),params)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<BaseListResult<GoodsInfo>>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        compositeDisposable.add(d);
                    }

                    @Override
                    public void onNext(BaseListResult<GoodsInfo> result) {
                        Trace.e("wcj+++++++"+result.getMsg());
                        if (result.isSuccess()){
                            if (null != result.getInfo() && null != result.getInfo() && result.getInfo().size() > 0){
                                view.onBarCodeLoadSuccess(result.getInfo().get(0));
                            }else {
                                view.onError("暂无该商品数据");
                            }
                        }else {
                            view.onError(result.getMsg());
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        Trace.e("wcj+++++++"+e.getMessage());
                        view.onError(e.getMessage());
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    /**
     * 扫描返回的二维码返回的标签
     * @param data
     */
    public void getQrCodeHttp(final String data) {
        Map<String, String> params = new HashMap<>();
        StringBuilder builder = new StringBuilder();
        builder.append(PreferenceUtil.getInstance().getString(PreferenceUtil.BRAND_ID,""));
        builder.append("|");
        builder.append(PreferenceUtil.getInstance().getInt(PreferenceUtil.USER_ID,0));
        builder.append("|");
        builder.append(PreferenceUtil.getInstance().getString(PreferenceUtil.TOKEN,""));
        builder.append("|");
        builder.append(0);
        builder.append("|");
        params.put("brandtoken", builder.toString());
        params.put("code", data);
        params.put("type", "0");
        params.put("timeStamp", System.currentTimeMillis() / 1000 + "");//加时间戳参数
        params.put("sign", MD5Util.md5(params));//md5加密并加参数
        view.onLoading();
        RetrofitManager.getDefault().create(ApiServer.class).getQrCodeHttp(RetrofitManager.getHeader(),params)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<BaseResult<EpcInfo>>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        compositeDisposable.add(d);
                    }

                    @Override
                    public void onNext(BaseResult<EpcInfo> result) {
                        Trace.e("wcj+++++++"+result.getMsg());
                        if (result.isSuccess()){
                            if (null != result.getData()){
                                view.onQrCodeLoadSuccess(result.getData());
                            }else {
                                view.onError(result.getMsg());
                            }
                        }else {
                            view.onError(result.getMsg());
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        Trace.e("wcj+++++++"+e.getMessage());
                        view.onError(e.getMessage());
                    }

                    @Override
                    public void onComplete() {

                    }
                });

    }

    /**
     * 缓存当前品牌下所有商品
     */
    public void cacheGoodsList() {
        recordInfoList= GreenDaoUtils.getSingleTon().getmDaoSession().getRecordInfoDao().queryBuilder()
                .where(RecordInfoDao.Properties.Type.eq(Constants.GLOBAL_GOODS_INFO))
                .list();
        if (null == recordInfoList || recordInfoList.size() == 0){//如果为空说明是第一次进来直接进行缓存
            gotoHttpData();
        }else {
            if ( System.currentTimeMillis() -recordInfoList.get(0).getUpdate_time() >= times_long){
                gotoHttpData();
                Trace.e("wcj更新时间：======"+recordInfoList.get(0).getUpdate_time());
            }
        }

    }

    private void gotoHttpData() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                Looper.prepare();
                getCacheList();
                Looper.loop();
            }
        }).start();
    }

    //===================
    /**
     * 缓存全局商品数据
     */
    private void getCacheList() {
        Map<String, String> params = new HashMap<>();
        StringBuilder builder = new StringBuilder();
        builder.append(PreferenceUtil.getInstance().getString(PreferenceUtil.BRAND_ID,""));
        builder.append("|");
        builder.append(PreferenceUtil.getInstance().getInt(PreferenceUtil.USER_ID,0));
        builder.append("|");
        builder.append(PreferenceUtil.getInstance().getString(PreferenceUtil.TOKEN,""));
        builder.append("|");
        builder.append(0);
        builder.append("|");
        params.put("brandtoken", builder.toString());
        params.put("store_type", "1");
        params.put("timeStamp", System.currentTimeMillis() / 1000 + "");//加时间戳参数
        params.put("sign", MD5Util.md5(params));//md5加密并加参数
        handler.sendEmptyMessage(ON_LOADING);
        RetrofitManager.getDefault().create(ApiServer.class).getGlobalListForCache(RetrofitManager.getHeader(),params)
                .retryWhen(new Function<Observable<Throwable>, ObservableSource<?>>() {
                    @Override
                    public ObservableSource<?> apply(Observable<Throwable> throwableObservable) throws Exception {
                        return throwableObservable.flatMap(new Function<Throwable, ObservableSource<?>>() {
                            @Override
                            public ObservableSource<?> apply(Throwable throwable) throws Exception {
                                // 输出异常信息
                                Trace.e("wcj,Tag+++++：" + throwable.toString());
                                /**
                                 * 需求1：根据异常类型选择是否重试
                                 * 即，当发生的异常 = 网络异常 = IO异常 才选择重试
                                 */
//                                if (throwable instanceof IOException) {
//                                    Trace.e("wcj+++++：" + "属于IO异常，需重试");
                                /**
                                 * 需求2：限制重试次数
                                 * 即，当已重试次数 < 设置的重试次数，才选择重试
                                 */
                                if (currentRetryGlobalCount < maxConnectCount) {
                                    // 记录重试次数
                                    currentRetryGlobalCount++;
                                    Trace.e("wcj,Tag+++++：重复次数" + +currentRetryGlobalCount);
                                    /**
                                     *  需求2：实现重试
                                     *  通过返回的Observable发送的事件 = Next事件，从而使得retryWhen（）重订阅，最终实现重试功能
                                     *  * *
                                     *  需求3：延迟1段时间再重试
                                     *  * 采用delay操作符 = 延迟一段时间发送，以实现重试间隔设置
                                     *  *
                                     *  * 需求4：遇到的异常越多，时间越长 *
                                     *  在delay操作符的等待时间内设置 = 每重试1次，增多延迟重试时间1s *
                                     */
                                    // 设置等待时间
                                    waitRetryGlobalTime = 1000 + waitRetryGlobalTime * 1000;
                                    Trace.e("wcj,Tag+++++： 等待时间 =" + waitRetryGlobalTime);
                                    return Observable.just(1).delay(waitRetryGlobalTime, TimeUnit.MILLISECONDS);
                                } else {
                                    // 若重试次数已 > 设置重试次数，则不重试
                                    // 通过发送error来停止重试（可在观察者的onError（）中获取信息）
                                    return Observable.error(new Throwable("重试次数已超过设置次数 = " + currentRetryGlobalCount + "，即 不再重试"));
                                }
//                                }
                                // 若发生的异常不属于I/O异常，则不重试
                                // 通过返回的Observable发送的事件 = Error事件 实现（可在观察者的onError（）中获取信息）
//                                else {
//                                    return Observable.error(new Throwable("发生了非网络异常（非I/O异常）"));
//                                }
                            }
                        });
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<BaseListResult<GlobalGoodsInfo>>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        compositeDisposable.add(d);
                    }

                    @Override
                    public void onNext(BaseListResult<GlobalGoodsInfo> result) {
                        Trace.e("wcj========="+result.getMsg());
                        if (result.isSuccess()){
                            GreenDaoUtils.getSingleTon().getmDaoSession().getGlobalGoodsInfoDao().deleteAll();
                            GreenDaoUtils.getSingleTon().getmDaoSession().getGlobalGoodsInfoDao().insertOrReplaceInTx(result.getData());
                            handler.sendEmptyMessage(ON_SUCCESS);
                            updateGlobalGoodInfo();
                        }else {
                            handler.sendEmptyMessage(ON_ERROR);
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        Trace.e("wcj========="+e.getMessage());
                        handler.sendEmptyMessage(ON_ERROR);
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    //===================


    /**
     * 缓存全局商品数据[byte形式的]
     */
//    private void getCacheList() {
//        Trace.e("重连次数："+ retryGlobalGoodsCount);
//
//        Map<String, String> params = RetrofitManager.getParams();
//        params.put("store_type", "1");
//        Map<String,String> header = RetrofitManager.getHeader();
//        header.put("gzip_type","1");
//
//        handler.sendEmptyMessage(ON_LOADING);
//        RetrofitManager.getDefault().create(ApiServer.class).getGlobalListByteForCache(header,params)
//                .enqueue(callbackCacheList);
//    }

    private int retryGlobalGoodsCount = 0;//重试次数
    private int reTryGlobalGoodsMax = 20;//重试最大次数，超过就关闭
    private long reTryGlobalGoodsDelay = 1500;//重试间隔，1.5s
    private Callback<ResponseBody> callbackCacheList = new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
            Trace.e("wcj时间差,压缩后的======="+(System.currentTimeMillis()-time_difference));
            try {
                if (null != response && null != response.body()) {
                    if (null != response.body().source() && response.isSuccessful()) {
                        retryGlobalGoodsCount = 0;
                        //获得response中的body的字节数组
//                                    byte[] data = response.body().bytes();
                        //通过UTF-8解压缩成json字符串
                        String json = GZIPUtils.uncompressToString(response.body().source().readByteArray(), GZIPUtils.GZIP_ENCODE_UTF_8);
                        //将字符串转换成定义好的数据类型
                        final JSONObject jsonObject = new JSONObject(json);
                        time_difference = System.currentTimeMillis();
                        // 对数据进行操作
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                cacheGoodsListNext(jsonObject);
                            }
                        }).start();

                    }else {
                        // todo 返回的字节数组无数据
                        if (retryGlobalGoodsCount < reTryGlobalGoodsMax) {
                            retryGlobalGoodsCount++;
                            Message msg = new Message();
                            msg.what = RETRY_CACHE_GLOBAL;
                            handler.sendMessageDelayed(msg, reTryGlobalGoodsDelay);
                        }else {
                            retryGlobalGoodsCount = 0;//重置
                            Message msg = new Message();
                            msg.obj = "网络异常";
                            msg.what = ON_ERROR;
                            handler.sendMessage(msg);
                        }
                    }
                }else {
                    // TODO 网络异常
                    if (retryGlobalGoodsCount < reTryGlobalGoodsMax) {
                        retryGlobalGoodsCount++;
                        Message msg = new Message();
                        msg.what = RETRY_CACHE_GLOBAL;
                        handler.sendMessageDelayed(msg, reTryGlobalGoodsDelay);
                    }else {
                        retryGlobalGoodsCount = 0;//重置
                        Message msg = new Message();
                        msg.obj = "网络异常";
                        msg.what = ON_ERROR;
                        handler.sendMessage(msg);
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
            if (retryGlobalGoodsCount < reTryGlobalGoodsMax) {
                retryGlobalGoodsCount++;
                Message msg = new Message();
                msg.what = RETRY_CACHE_GLOBAL;
                handler.sendMessageDelayed(msg, reTryGlobalGoodsDelay);
            }else {
                retryGlobalGoodsCount = 0;//重置
                Message msg = new Message();
                msg.obj = "网络异常";
                msg.what = ON_ERROR;
                handler.sendMessage(msg);
            }
        }
    };

    /**
     * 对全局商品缓存
     * @param jsonObject
     */
    private void cacheGoodsListNext(JSONObject jsonObject){
        Trace.i("wcj："+jsonObject.toString());
        Trace.e("wcj：当前线程"+Looper.myLooper());
        boolean isSuccess = jsonObject.optBoolean("success");
        if (isSuccess) {
            JSONArray jsonArray = jsonObject.optJSONArray("data");
            if (jsonArray.length() == 0)return;
            final List<GlobalGoodsInfo> list = GsonFactory.getObjectList(jsonArray.toString(),GlobalGoodsInfo.class);
            if (null != list && list.size() > 0) {
                GreenDaoUtils.getSingleTon().getmDaoSession().getGlobalGoodsInfoDao().deleteAll();
                GreenDaoUtils.getSingleTon().getmDaoSession().getGlobalGoodsInfoDao().insertOrReplaceInTx(list);
                PreferenceUtil.getInstance().commitBoolean(PreferenceUtil.LABEL_IS_LOADED, true);//本地记录加载成功
                updateGlobalGoodInfo();
                handler.sendEmptyMessage(ON_SUCCESS);
            } else {
                //本地记录一个参数，list.size() < 100：加载完毕
                PreferenceUtil.getInstance().commitBoolean(PreferenceUtil.LABEL_IS_LOADED, true);//本地记录加载成功
                handler.sendEmptyMessage(ON_SUCCESS);
            }
        } else {
            handler.sendEmptyMessage(ON_ERROR);
        }
    }


    private void updateGlobalGoodInfo() {
        //对更新后的数据进行记录
        if (null == recordInfoList || recordInfoList.size() == 0){
            RecordInfo recordInfo = new RecordInfo();
            recordInfo.setType(Constants.GLOBAL_GOODS_INFO);
            recordInfo.setUpdate_time(System.currentTimeMillis());
            GreenDaoUtils.getSingleTon().getmDaoSession().getRecordInfoDao().insertOrReplace(recordInfo);
        }else {
            if ( System.currentTimeMillis() - recordInfoList.get(0).getUpdate_time() >= times_long){
                recordInfoList.get(0).setUpdate_time(System.currentTimeMillis());
                GreenDaoUtils.getSingleTon().getmDaoSession().getRecordInfoDao().insertOrReplace(recordInfoList.get(0));
                Trace.e("wcj最新更新时间：======"+recordInfoList.get(0).getUpdate_time());
            }
        }
    }

    /**
     * 检查版本号是否需要更新
     */
    public void checkVersion() {
        Map<String,String> params = new HashMap<>();
        params.put("apptype", "1");
        params.put("app_package", DeviceUtils.getPackerName(context()));
        params.put("timeStamp", System.currentTimeMillis() / 1000 + "");//加时间戳参数
        params.put("sign", MD5Util.md5(params));//md5加密并加参数
        RetrofitManager.getDefault().create(ApiServer.class).getVersionUpdate(RetrofitManager.getHeader(),params)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<BaseListResult<UpdateBean>>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        compositeDisposable.add(d);
                    }

                    @Override
                    public void onNext(BaseListResult<UpdateBean> result) {
                        if (result.isSuccess()){
                            if (null != result.getList() && result.getList().size() > 0){
                                UpdateBean data = result.getList().get(0);
                                if (DeviceUtils.compareVersion(data.getOld_version(),DeviceUtils.getVersionName(context())) == 1) {
                                    view.onForceUpdate(false, data);
                                } else if (DeviceUtils.compareVersion(data.getNew_version(),DeviceUtils.getVersionName(context())) == 1) {
                                    view.onForceUpdate(false, data);
                                } else {
                                    view.noUpdate();
                                }
                            }else {
                                view.noUpdate();
                            }
                        }else {
                            view.noUpdate();
                        }

                    }

                    @Override
                    public void onError(Throwable e) {
                        view.noUpdate();
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }
}
